<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>23.__proto__原来是属性访问器</title>
</head>

<body>
</body>
<script>
  // proto 虽然不推荐使用，但是还是被很多人用到
  //1. 严格的讲，proto 不是一个属性，是prototype的getter/setter 实现，他是一个非标准的定义
  //2. __proto__ 内部使用getter/setter 控制值，所以只允许对象或 null
  //3. 建议使用 Object.setPrototypeOf 与Object.getProttoeypOf 替代 __proto__
  let hd = { name: 'houdunren' };
  hd.__proto__ = {
    show () {
      console.log(this.name);
    }
  };
  // 这行代码不会生效，因为 __proto__ 内部是getter/setter设置的，不是标准的属性，只能赋值为Object或nullß
  hd.__proto__ = 99;
  hd.show();
  console.log(hd);  //show : ƒ show() [[Prototype]] : get __proto__ : ƒ __proto__() set __proto__ : ƒ __proto__()

  // 原理如下，proto作为一个伪造属性，只能接受Object类型的赋值
  hd = {
    action: {},
    get proto () {
      return this.action;
    },
    set proto (obj) {
      if (obj instanceof Object) {
        this.action = obj;
      }
    }
  };
  console.log();
  hd.proto = { view: function () { } };
  hd.proto = 100;
  console.log(hd);//{action: {…}} action : {view: ƒ} proto : Object get proto : ƒ proto() set proto : ƒ proto(obj) [[Prototype]] : Object
  //如果一定要使用 proto 属性,那么就要让对象没有原型，因为  __proto__属性存在于 Object.prototype中，没有原型的对象__proto__属性就可以赋值为 字符串类型了
   hd = Object.create(null);
  console.dir(hd.__proto__);
  hd.__proto__ ="后盾人";
  console.log(hd.__proto__);
</script>

</html>